# -*- coding: utf-8 -*-
#   /**
#   * Copyright (c) 2022 Beijing Jiaotong University
#   * PhotLab is licensed under [Open Source License].
#   * You can use this software according to the terms and conditions of the [Open Source License].
#   * You may obtain a copy of [Open Source License] at: [https://open.source.license/]
#   *
#   * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
#   * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
#   * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
#   *
#   * See the [Open Source License] for more details.
#   */
#   /**
#   * Author: Zheng Wang
#   * Created: Feb. 14, 2024
#   * Supported by: National Key Research and Development Program of China
#   */
import logging
import numpy as np


class RandomConst:
    """
        A Random const generator used to generate a random const number
    """

    def __init__(self, distribution="Uniform",
                 lower_bound=-1e100,
                 upper_bound=1e100,
                 mean=0.0,
                 std=1):
        """
            指数分布会使用均值mean，正太分布会使用均值和方差
        :param distribution:  随机数分布(Uniform,Exponential,Normal)
        :param lower_bound: 数值下界
        :param upper_bound: 数值上界
        :param mean: 均值
        :param std: 标准差
        """
        if lower_bound > upper_bound:
            """
                用户把上下界搞混了
            """
            logging.warning("The specified lower bound:{} is greater than the upper bound:{}."
                            " It has been automatically reversed for you. Please take note."
                            .format(lower_bound,upper_bound))
            self.__distribution = distribution
            self.__lower_bound = upper_bound
            self.__upper_bound = lower_bound
            self.__mean = mean
            self.__std = std
        else:
            self.__distribution = distribution
            self.__lower_bound = lower_bound
            self.__upper_bound = upper_bound
            self.__mean = mean
            self.__std = std

    def calculate(self):
        if self.__distribution == "Uniform":
            return np.random.uniform(self.__lower_bound, self.__upper_bound)
        elif self.__distribution == "Exponential":
            random_number = np.random.exponential(scale = self.__mean,size = None) * \
                            (self.__upper_bound - self.__lower_bound) + self.__lower_bound
            return random_number
        elif self.__distribution == "Normal":
            random_number = np.random.normal(self.__mean, self.__std)
            random_number_clip = np.clip(random_number, self.__lower_bound, self.__upper_bound)
            return self.__upper_bound
        else:
            logging.warning("Fetch an unknown random distribution type, return 0.0")
            return 0.0


if __name__ == '__main__':
    random_const = RandomConst(distribution="Exponential",
                               lower_bound=1,
                               upper_bound=10,
                               mean=1.0,
                               std=1)
    print(random_const.calculate())
